#!/usr/bin/env python3
"""
抖音图片URL格式分析器
用于测试和分析抖音图片的真实可访问格式
"""

import requests
import re
import json
from urllib.parse import urlparse, parse_qs, urlencode
import time

class DouyinImageAnalyzer:
    def __init__(self):
        self.session = requests.Session()
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
            'Accept-Encoding': 'gzip, deflate',
            'Connection': 'keep-alive',
            'Upgrade-Insecure-Requests': '1',
        })
        
    def analyze_tplv_parameter(self, tplv_value):
        """分析tplv参数的结构"""
        print(f"\n=== 分析TPLV参数: {tplv_value} ===")
        
        # 常见的tplv参数格式分析
        patterns = {
            'size_format': r'(\d+)x(\d+)',
            'quality': r'q_(\d+)',
            'format': r'\.(\w+)$',
            'processing_code': r'([a-zA-Z0-9\-_]+)',
        }
        
        for pattern_name, pattern in patterns.items():
            matches = re.findall(pattern, tplv_value)
            if matches:
                print(f"  {pattern_name}: {matches}")
    
    def generate_url_variants(self, base_url, image_id):
        """生成不同格式的URL变体进行测试"""
        variants = []
        
        # 基础域名变体
        domains = [
            'p1-sign.toutiaoimg.com',
            'p3-sign.toutiaoimg.com',
            'p6-sign.toutiaoimg.com',
            'p9-sign.toutiaoimg.com',
            'p1.toutiaoimg.com',
            'p3.toutiaoimg.com',
            'p6.toutiaoimg.com',
            'p9.toutiaoimg.com',
            'sf1-cdn-tos.douyinstatic.com',
            'sf3-cdn-tos.douyinstatic.com',
            'sf6-cdn-tos.douyinstatic.com',
        ]
        
        # 常见的tplv参数变体
        tplv_variants = [
            'obj-web-1:0:0:0',
            '5mmsx3fupr-image',
            '5mmsx3fupr-image.jpeg',
            'dy-sq-crop-tos:800:800',
            'dy-sq-crop-tos:1080:1080',
            'dy-crop-tos:800:800',
            'large',
            'medium',
            'small',
            'origin',
        ]
        
        for domain in domains:
            for tplv in tplv_variants:
                # 构建不同格式的URL
                url_variants = [
                    f"https://{domain}/tos-cn-i-0813/{image_id}~tplv-{tplv}.image",
                    f"https://{domain}/tos-cn-i-0813/{image_id}~tplv-{tplv}.jpeg",
                    f"https://{domain}/tos-cn-i-0813/{image_id}~tplv-{tplv}.webp",
                    f"https://{domain}/tos-cn-i-0813c/{image_id}~tplv-{tplv}.image",
                    f"https://{domain}/obj/tos-cn-i-0813/{image_id}~tplv-{tplv}.image",
                    f"https://{domain}/obj/tos-cn-i-0813c/{image_id}~tplv-{tplv}.image",
                    f"https://{domain}/{image_id}~tplv-{tplv}.image",
                    f"https://{domain}/{image_id}",
                ]
                variants.extend(url_variants)
        
        return list(set(variants))  # 去重
    
    def test_url_accessibility(self, url, timeout=10):
        """测试URL的可访问性"""
        try:
            response = self.session.head(url, timeout=timeout, allow_redirects=True)
            return {
                'url': url,
                'status_code': response.status_code,
                'accessible': response.status_code == 200,
                'content_type': response.headers.get('Content-Type', ''),
                'content_length': response.headers.get('Content-Length', ''),
                'final_url': response.url if response.url != url else None,
                'error': None
            }
        except Exception as e:
            return {
                'url': url,
                'status_code': None,
                'accessible': False,
                'content_type': '',
                'content_length': '',
                'final_url': None,
                'error': str(e)
            }
    
    def extract_image_info_from_url(self, douyin_url):
        """从抖音URL中提取图片相关信息"""
        print(f"\n=== 分析抖音URL ===")
        print(f"URL: {douyin_url}")
        
        # 解析URL
        parsed = urlparse(douyin_url)
        params = parse_qs(parsed.query)
        
        print(f"域名: {parsed.netloc}")
        print(f"路径: {parsed.path}")
        print(f"参数: {json.dumps(params, indent=2, ensure_ascii=False)}")
        
        # 提取可能的图片ID
        path_parts = parsed.path.strip('/').split('/')
        if len(path_parts) >= 3 and path_parts[0] == 'share' and path_parts[1] == 'note':
            note_id = path_parts[2]
            print(f"笔记ID: {note_id}")
            return note_id
        
        return None
    
    def analyze_example_urls(self):
        """分析一些示例URL格式"""
        example_urls = [
            # 常见的抖音图片URL格式示例
            "https://p1-sign.toutiaoimg.com/tos-cn-i-0813/abc123~tplv-5mmsx3fupr-image.jpeg",
            "https://p3-sign.toutiaoimg.com/obj/tos-cn-i-0813c/def456~tplv-dy-sq-crop-tos:800:800.webp",
            "https://sf6-cdn-tos.douyinstatic.com/obj/tos-cn-i-0813/ghi789~tplv-obj-web-1:0:0:0.image",
        ]
        
        print("\n=== 分析示例URL格式 ===")
        for url in example_urls:
            print(f"\nURL: {url}")
            parsed = urlparse(url)
            path = parsed.path
            
            # 提取tplv参数
            tplv_match = re.search(r'~tplv-([^.]+)', path)
            if tplv_match:
                tplv_value = tplv_match.group(1)
                self.analyze_tplv_parameter(tplv_value)
            
            # 提取图片ID
            id_match = re.search(r'/([^/~]+)~tplv', path)
            if id_match:
                image_id = id_match.group(1)
                print(f"  图片ID: {image_id}")
            
            # 分析域名
            print(f"  域名: {parsed.netloc}")
            print(f"  路径结构: {path}")
    
    def test_common_patterns(self, image_id):
        """测试常见的URL模式"""
        print(f"\n=== 测试图片ID {image_id} 的不同URL格式 ===")
        
        variants = self.generate_url_variants("", image_id)
        accessible_urls = []
        
        print(f"生成了 {len(variants)} 个URL变体进行测试...")
        
        for i, url in enumerate(variants[:50]):  # 限制测试数量以避免过多请求
            result = self.test_url_accessibility(url)
            if result['accessible']:
                accessible_urls.append(result)
                print(f"✓ 可访问: {url}")
                print(f"  状态码: {result['status_code']}")
                print(f"  内容类型: {result['content_type']}")
                print(f"  内容长度: {result['content_length']}")
            elif i % 10 == 0:  # 每10个打印一次进度
                print(f"已测试 {i+1}/{len(variants[:50])} 个URL...")
            
            time.sleep(0.1)  # 避免请求过快
        
        return accessible_urls
    
    def run_analysis(self, douyin_url):
        """运行完整的分析流程"""
        print("🔍 抖音图片URL格式分析器")
        print("=" * 50)
        
        # 1. 分析示例URL格式
        self.analyze_example_urls()
        
        # 2. 从抖音URL提取信息
        image_id = self.extract_image_info_from_url(douyin_url)
        
        # 3. 如果有图片ID，测试不同格式
        if image_id:
            accessible_urls = self.test_common_patterns(image_id)
            
            print(f"\n=== 分析结果 ===")
            print(f"找到 {len(accessible_urls)} 个可访问的URL")
            
            for result in accessible_urls:
                print(f"✓ {result['url']}")
        else:
            print("\n⚠️ 无法从URL中提取图片ID")
        
        # 4. 总结常见模式
        print("\n=== 常见URL模式总结 ===")
        print("1. 域名格式:")
        print("   - p[1,3,6,9]-sign.toutiaoimg.com (带签名)")
        print("   - p[1,3,6,9].toutiaoimg.com (无签名)")
        print("   - sf[1,3,6]-cdn-tos.douyinstatic.com")
        print("\n2. 路径格式:")
        print("   - /tos-cn-i-0813/{image_id}~tplv-{params}.{ext}")
        print("   - /obj/tos-cn-i-0813/{image_id}~tplv-{params}.{ext}")
        print("\n3. TPLV参数:")
        print("   - 5mmsx3fupr-image: 通用图片处理")
        print("   - dy-sq-crop-tos:800:800: 方形裁剪800x800")
        print("   - obj-web-1:0:0:0: Web对象格式")
        print("\n4. 文件扩展名:")
        print("   - .image (通用)")
        print("   - .jpeg")
        print("   - .webp")

def main():
    analyzer = DouyinImageAnalyzer()
    
    # 测试URL
    test_url = "https://www.iesdouyin.com/share/note/7539762738609524028/?from_ssr=1&video_share_track_ver=&did=MS4wLjABAAAApvjF68UUTX4OETPHqm6Qb1n50w5hWfK1o5yt9-W9DxzSGtvWBPEVBi2JbL-BZqJG&mid=7353586197106969394&ts=1755505281&region=CN&share_sign=_KM3zRnfkSrYlb6O_W4WpmZDi93S1DgwbitrykgWoTw-&tt_from=share_to&with_sec_did=1&from_aid=1128&titleType=title&utm_source=share_to&utm_medium=ios&activity_info=%7B%22social_share_time%22:%221755505285%22,%22social_author_id%22:%2293866431509%22,%22social_share_id%22:%22100713632338_1755505285%22,%22social_share_user_id%22:%22100713632338%22%7D&timestamp=1755505285&share_version=350200&u_code=16d7el05l&iid=MS4wLjABAAAAZZxBDMRKoP6HC0BU_2pKdv_Zbd-NIvMD4rVc0SpIiW0mLVp0eiRAVtU6&utm_campaign=client_share&app=aweme&schema_type=37"
    
    analyzer.run_analysis(test_url)

if __name__ == "__main__":
    main()